<template>
    <div class="video-main">
        <div class="video-container">
            <video ref="localVideo" class="local-video"></video>
            <video ref="remoteVideo" class="remote-video"></video>
            <div v-if="socketService.caller && socketService.calling" class="caller-overlay">
                <p class="overlay-text">等待对方接听...</p>
                <img @click="hangUp" src="/src/assets/svg/refuse.svg" class="overlay-icon" alt="">
            </div>
            <div v-if="socketService.called && socketService.calling" class="called-overlay">
                <p class="overlay-text">收到视频邀请...</p>
                <div class="overlay-buttons">
                    <img @click="hangUp" src="/src/assets/svg/refuse.svg" class="overlay-icon" alt="">
                    <img @click="acceptCall" src="/src/assets/svg/accept.svg" class="overlay-icon" alt="">
                </div>
            </div>
            <div v-if="socketService.communicating" class="called-overlay">
                <p class="overlay-text">挂断</p>
                <div class="overlay-buttons">
                    <img @click="hangUp" src="/src/assets/svg/refuse.svg" class="overlay-icon" alt="">
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { useSocketStore } from '@/stores/socketStore'
import { ref, onMounted } from 'vue'

const socketService = useSocketStore();
const localVideo = ref<HTMLVideoElement>();// video标签实例，播放本人的视频
const remoteVideo = ref<HTMLVideoElement>();// video标签实例，播放对方的视频
const localStream = ref<any>()
const peer = ref<any>();

onMounted(async () => {
    callRemote();

    socketService.socket.on('acceptCall', async () => {
        if (socketService.caller) {
            // 用户A收到用户B同意视频的请求
            peer.value = new RTCPeerConnection()

            // 添加本地音视频流，生成offer
            peer.value.addStream(localStream.value)

            // 通过onicecandidate事件获取candidate信息
            peer.value.onicecandidate = (event:any) => {
                // console.log('用户A的candidate信息', event.candidate);
                if (event.candidate) {
                    // 向服务器发送candidate信息
                    socketService.socket?.emit('sendCandidate', { roomId: socketService.roomId, candidate: event.candidate })
                }
            }

            // 监听onaddstream来获取对方的音视频流
            peer.value.onaddstream = (event:any) => {
                // console.log('用户A收到用户B的stream', event.stream);
                socketService.communicating = true;
                socketService.calling = false;
                remoteVideo.value!.srcObject = event.stream
                remoteVideo.value!.play();
            }

            // 生成offer
            const offer = await peer.value.createOffer({
                offerToReceiveAudio: 1,
                offerToReceiveVideo: 1
            })

            // console.log(offer);

            // 再本地设置offer信息
            await peer.value.setLocalDescription(offer);

            //发送offer 
            socketService.socket?.emit('sendOffer', { offer, roomId: socketService.roomId })
        }
    })

    /**用户B收到用户A的offer */
    socketService.socket.on('sendOffer', async (offer) => {
        if (socketService.called) { // 接收端，使用 value 属性获取 ref 的值
            /**用户B需要创建自己的RTCPeerConnection，
              * 添加本地音视频流，
              * 设置远端描述信息SDP，
              * 生成answer，
              * 并且通过信令服务器发送给用户A
              */
            // 收到offer
            // console.log(offer);
            // 用户B需要创建自己的RTCPeerConnection
            peer.value = new RTCPeerConnection();
            // 添加本地音视频流
            const stream = await getLocalStream();
            peer.value.addStream(stream);

            // 通过监听onicecandidate事件获取candidate信息
            peer.value.onicecandidate = (event:any) => {
                if (event.candidate) {
                    socketService.socket?.emit('sendCandidate', {
                        roomId: socketService.roomId,
                        candidate: event.candidate
                    });
                }
            };

            peer.value.onaddstream = (event:any) => {
                // console.log('用户B收到用户A的stream', event.stream);
                socketService.communicating = true;
                socketService.calling = false;
                remoteVideo.value!.srcObject = event.stream;
                remoteVideo.value!.play();
            };

            // 设置远端描述信息,SDP
            await peer.value.setRemoteDescription(offer);
            // 生成answer
            const answer = await peer.value.createAnswer();
            // console.log('answer:', answer);
            // 在本地设置answer信息
            await peer.value.setLocalDescription(answer);

            // 发送answer
            socketService.socket?.emit('sendAnswer', {
                answer,
                roomId: socketService.roomId
            });
        }
    });

    // 收到answer
    socketService.socket.on('sendAnswer', async (answer) => {
        if (socketService.caller) {
            /**用户A收到用户B的answer */

            // console.log(answer);
            // 设置远端answer信息
            await peer.value.setRemoteDescription(answer);
        }
    })
    // 收到candidate信息
    socketService.socket.on('sendCandidate', async (candidate) => {
        // console.log(candidate);
        await peer.value.addIceCandidate(candidate);
    })
    socketService.socket.on('hangUp', () => {
        socketService.caller = false;
        socketService.called = false;
        socketService.communicating = false;
        if (localStream.value) {
          const tracks = localStream.value.getTracks();
          tracks.forEach((track:any) => track.stop());
          localVideo.value!.srcObject = null;
        }
        
        // 关闭 RTCPeerConnection 连接
        if (peer.value) {
          peer.value.close();
        }
        remoteVideo.value!.srcObject = null
      })

});

// 发起方发起视频请求
const callRemote = async () => {
  // console.log('发起视频');
  // 用户A向用户B发送视频请求
  await getLocalStream();
  // 通过信令服务器向用户B发起视频请求
  socketService.socket?.emit('callRemote', socketService.roomId)

}

// 获取本地音视频流
const getLocalStream = async () => {
    // console.log("打开视频");

    const stream = await navigator.mediaDevices.getUserMedia({// 获取音视频流
        audio: true,
        video: true
    })

    localVideo.value!.srcObject = stream
    localVideo.value!.play()

    localStream.value = stream;
    // console.log(localStream.value)
    return stream
}
// 挂断视频
const hangUp = () => {
    // console.log('挂断视频');
    socketService.communicating = false;
    // 停止本地视频流
    // const localStream = localStream.value;
    socketService.called = false;

    if (localStream.value) {
        const tracks = localStream.value.getTracks();
        tracks.forEach((track:any) => track.stop());
        localVideo.value!.srcObject = null;
    }

    // 关闭 RTCPeerConnection 连接
    if (peer.value) {
        peer.value.close();
    }

    // 通过信令服务器通知对方挂断视频
    socketService.socket?.emit('hangUp', socketService.roomId);
}

// 接收方同意视频请求
const acceptCall = () => {
    // console.log('同意视频通话');
    socketService.socket?.emit('acceptCall', socketService.roomId)
}
</script>

<style scoped>
.video-main {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    width: 100%;
    padding: 48px;
}

.video-container {
    position: relative;
    height: 100%;
    width: 100%;
    margin-bottom: 1rem;
}

.local-video {
    width: 100%;
    height: 100%;
    background-color: #eee;
    object-fit: cover;
}

.remote-video {
    width: 32px;
    height: 48px;
    position: absolute;
    bottom: 0;
    right: 0;
    object-fit: cover;
}

.caller-overlay {
    position: absolute;
    top: 66.66%;
    /* left: 36px; */
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
}

.overlay-text {
    margin-bottom: 4px;
    color: #fff;
}

.overlay-icon {
    width: 16px;
    cursor: pointer;
}

.called-overlay {
    position: absolute;
    width: 100%;
    top: 66.66%;
    width: 100%;
    /* left: 32px; */
    display: flex;
    flex-direction: column;
    align-items: center;
}

.overlay-buttons {
    display: flex;
    align-items: center;

}

.button-group {
    display: flex;
    gap: 2px;
    margin-bottom: 4px;
}

.video-button {
    border-radius: 4px;
    background-color: #4f46e5;
    color: #fff;
    padding: 4px 8px;
    font-weight: bold;
    font-size: 14px;
    cursor: pointer;
}

.hangup-button {
    border-radius: 4px;
    background-color: #e53e3e;
    color: #fff;
    padding: 4px 8px;
    font-weight: bold;
    font-size: 14px;
    cursor: pointer;
}
</style>
